import * as THREE from 'three';
import M from 'scripts/main.js';
import { TWEEN } from 'three/addons/libs/tween.module.min.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
import {City} from 'scripts/city.js';
import {BuyBuilding} from 'scripts/buyBuilding.js';

class Market {
	constructor(){	
		let animationID;

		let camera, scene, group, renderer, controls;
		let objects = [],targets = [];
		const m = new M();

		init();

		function init() {
			THREE.Cache.enabled = true;
			m.display("goback",true);
			m.getNode("goback").addEventListener('pointerdown', goback);
			window.addEventListener( 'resize', onWindowResize );

			camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1000, 10000 );
			camera.position.z = 0;
			scene = new THREE.Scene();

			group = new THREE.Group();
			scene.add( group );
						
			let buildings = [
				{name:'44三层塔',price:50000},
				{name:'44城主府',price:44000},
				{name:'44演武场',price:44000},
				{name:'44市场',price:44000},
				{name:'44地坛',price:44000},
				{name:'44道观',price:44000},
				{name:'44仓库',price:44000},
				{name:'44带井大宅',price:44000},
				{name:'44偏门大宅',price:44000},
				{name:'43书院',price:43000},
				{name:'43大饭店',price:43000},
				{name:'33亭子',price:33000},
				{name:'32商店',price:32000},
				{name:'32庭院中宅',price:32000},
				{name:'32门楼',price:32000},
				{name:'32矿坑',price:32000},
				{name:'22杂货铺',price:22000},
				{name:'22小饭店',price:22000},
				{name:'22石匠店',price:22000},
				{name:'22角院',price:22000},
				{name:'22角屋',price:22000},
				{name:'22岗楼',price:22000},
				{name:'22二楼铺面',price:22000},
				{name:'22二层楼',price:22000},
				{name:'22布店',price:22000},
				{name:'22半院',price:22000},
				{name:'21柴房',price:21000},
				{name:'11斜顶小屋',price:11000},
				{name:'11尖顶小屋',price:11000},
				{name:'11大树',price:1000},
				{name:'11小树',price:500},
			];
			for ( let i = 0; i < buildings.length; i ++ ) {
				var building = buildings[i];
				const element = document.createElement( 'div' );
				element.className = 'building';
				element.index=i;
				element.tag = building;
				element.style.backgroundColor = 'rgba(0,127,127,0.2)';
				//这里是关键，不可以用click，估计是为了同时兼顾手机
				element.addEventListener('pointerdown', function() { 
					dismiss(1000,this.index);
					setTimeout(()=>{
						destroy();
						new BuyBuilding(this.tag);
					},1900);
				});

				const image = document.createElement( 'img' );
				image.className = 'image';
				image.src = m.current()+"images/"+building.name+".png";
				element.appendChild( image );

				const name = document.createElement( 'div' );
				name.className = 'name';
				name.textContent = building.name.substr(2);
				element.appendChild( name );

				const price = document.createElement( 'div' );
				price.className = 'price';
				price.innerHTML = "💰 " + building.price;
				element.appendChild( price );

				const objectCSS = new CSS3DObject( element );
				//必须将网页对象和3d对象关联起来，才能对其进行操作
				element.parent = objectCSS;
				objectCSS.position.x = Math.random() * 4000 - 2000;
				objectCSS.position.y = Math.random() * 4000 - 2000;
				objectCSS.position.z = Math.random() * 4000 - 5000;
				objectCSS.rotation.x = Math.random();
				objectCSS.rotation.y = Math.random();
				objectCSS.rotation.z = Math.random();
				group.add( objectCSS );

				objects.push( objectCSS );
				//图片旋转的弧度值，均匀的排成一圈。
				const theta = i * (2*Math.PI/buildings.length);
				const object = new THREE.Object3D();
				object.position.setFromCylindricalCoords( 1200, theta, 0 );
				//指向圆心的向量
				const vector = new THREE.Vector3();
				vector.x = object.position.x * 2;
				vector.y = 0;
				vector.z = object.position.z * 2;

				//使图片指向圆心
				object.lookAt( vector );
				//因为指向圆心之后图片是反的，所以翻转180度
				object.rotation.y -=  Math.PI;
				targets.push( object );
			}

			//

			renderer = new CSS3DRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.getElementById( 'container' ).appendChild( renderer.domElement );

			//

			const controls = new OrbitControls( camera, renderer.domElement );
			controls.target.set( 0.1, 0, 0 );
			controls.update();
			
			transform( 1000 );
			animate();
		}
		
		function goback(){
			destroy();
			new City();
		}
		
		function transform( duration ) {

			TWEEN.removeAll();

			for ( let i = 0; i < objects.length; i ++ ) {

				const object = objects[ i ];
				const target = targets[ i ];

				new TWEEN.Tween( object.position )
					.to( { x: target.position.x, y: target.position.y, z: target.position.z }, Math.random() * duration + duration )
					.easing( TWEEN.Easing.Exponential.InOut )
					.start();

				new TWEEN.Tween( object.rotation )
					.to( { x: target.rotation.x, y: target.rotation.y, z: target.rotation.z }, Math.random() * duration + duration )
					.easing( TWEEN.Easing.Exponential.InOut )
					.start();

			}

			new TWEEN.Tween( this )
				.to( {}, duration * 2 )
				.onUpdate( render )
				.start();

		}

		function dismiss(duration,index=0) {
			TWEEN.removeAll();
			for ( let i = 0; i < objects.length; i ++ ) {

				const object = objects[ i ];
				
				if (index==i){
					const theta = i * (2*Math.PI/objects.length);
					const obj = new THREE.Object3D();
					obj.position.setFromCylindricalCoords( -10000, theta, 0 );
					new TWEEN.Tween( object.position )
						.to( obj.position, duration*2 )
						.easing( TWEEN.Easing.Exponential.InOut )
						.start();
					
				}else{
					new TWEEN.Tween( object.position )
						.to( { x:  Math.random() * 4000 - 2000, y:  Math.random() * 4000 - 2000, z:  Math.random() * 4000 - 2000 }, Math.random() * duration + duration )
						.easing( TWEEN.Easing.Exponential.InOut )
						.start();

					new TWEEN.Tween( object.rotation )
						.to( { x: Math.random(), y: Math.random(), z: Math.random() }, Math.random() * duration + duration )
						.easing( TWEEN.Easing.Exponential.InOut )
						.start();
				}
			}

			new TWEEN.Tween( this )
				.to( {}, duration * 2 )
				.onUpdate( render )
				.start();
		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

			render();

		}

		function animate() {

			animationID = requestAnimationFrame( animate );
			group.rotation.y = - performance.now() / 25000;

			TWEEN.update();
			render();

		}

		function render() {

			renderer.render( scene, camera );

		}

		function destroy(){
			cancelAnimationFrame(animationID)
			TWEEN.removeAll();
			scene.clear();
			renderer.content = null;

			m.getNode("goback").removeEventListener('pointerdown', goback);
			window.removeEventListener( 'resize', onWindowResize );
			m.getNode("container").removeChild(renderer.domElement);
			scene = null;
			camera = null;
			controls = null;
			renderer = null;
			objects = null;
			targets = null;
		}			
	}
}
export { Market };